﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.Text.RegularExpressions;
using System.Collections.ObjectModel;
using University.Workshop.Model;
using System.Data;
using University.Workshop.WebApp.com.paypal.sandbox.www;
using System.Configuration;
using System.Web.Security;
using University.Workshop.DataAccess;

namespace University.Workshop.WebApp
{
    public partial class Checkout : System.Web.UI.Page
    {
        Collection<Product> prodList = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!User.Identity.IsAuthenticated)
            {
                FormsAuthentication.RedirectToLoginPage();
            }
            else
            {
                if (!IsPostBack)
                {
                    DataTable prodTable = new DataTable();
                    prodTable.Columns.Add("Name");
                    prodTable.Columns.Add("Quantity");
                    prodTable.Columns.Add("Price");
                    prodList = Session["list"] as Collection<Product>;
                    if (prodList != null)
                    {
                        double taxes = 0;
                        int shipping = 0;
                        double totalPrice = 0;
                        foreach (Product p in prodList)
                        {
                            double price = p.Price;
                            if (p.Currency == "Bolivianos")
                            {
                                price = System.Convert.ToDouble(Convert(System.Convert.ToDecimal(price), "BOB", "USD"));
                                price = Math.Round(price, 2);
                            }
                            totalPrice += price * p.Quantity;
                            taxes += 0.05 * price;
                            shipping += 5 * p.Quantity;
                            DataRow newRow = prodTable.NewRow();
                            newRow["Name"] = p.Name;
                            newRow["Quantity"] = p.Quantity;
                            newRow["Price"] = price;
                            prodTable.Rows.Add(newRow);
                            prodTable.AcceptChanges();
                        }
                        taxes = Math.Round(taxes, 2);
                        DataTable finalTable = new DataTable();
                        finalTable.Columns.Add("Description");
                        finalTable.Columns.Add("Price");
                        DataRow taxRow = finalTable.NewRow();
                        taxRow["Description"] = "Total taxes (5% of each product)";
                        taxRow["Price"] = taxes;
                        DataRow shippingRow = finalTable.NewRow();
                        shippingRow["Description"] = "Total shipping (5$ per item)";
                        shippingRow["Price"] = shipping;
                        DataRow totalRow = finalTable.NewRow();
                        totalRow["Description"] = "Order Total";
                        totalRow["Price"] = totalPrice + taxes + shipping;
                        finalTable.Rows.Add(taxRow);
                        finalTable.Rows.Add(shippingRow);
                        finalTable.Rows.Add(totalRow);
                        Taxes.DataSource = finalTable;
                        Taxes.DataBind();
                        Products.DataSource = prodTable;
                        Products.DataBind();
                        this.Session.Add("ProdList", prodList);
                        this.Session.Add("ProdTable", prodTable);
                        this.Session.Add("FinalTable", finalTable);
                    }
                }
            }

        }

        private decimal Convert(decimal amount, string fromCurrency, string toCurrency)
        {
            WebClient web = new WebClient();
 
            string url = string.Format("http://www.google.com/ig/calculator?hl=en&q= {2}{0}%3D%3F{1}", fromCurrency.ToUpper(), toCurrency.ToUpper(), amount);
 
            string response = web.DownloadString(url);
 
            Regex regex = new Regex("rhs: \\\"(\\d*.\\d*)");
            Match match = regex.Match(response);
 
            decimal rate = System.Convert.ToDecimal(match.Groups[1].Value);
 
            return rate;
        }

        private bool checkPassword()
        {
            User user = UserDataAccess.UserExists(User.Identity.Name, xPassword.Text.GetHashCode().ToString());
            return user != null;
        }

        protected void PaypalCheckout(object sender, EventArgs e)
        {
            if (checkPassword())
            {
                prodList = Session["ProdList"] as Collection<Product>;
                DataTable prodTable = Session["ProdTable"] as DataTable;
                DataTable finalTable = Session["FinalTable"] as DataTable;
                if (prodList != null && finalTable != null && prodTable != null)
                {
                    long orderId = OrderDataAccess.AddNewOrder(prodList, UserDataAccess.GetUserByEmail(User.Identity.Name).Id);
                    SetExpressCheckoutRequestDetailsType reqDetails = new SetExpressCheckoutRequestDetailsType();

                    // Use HttpContext.ApplicationPath to get host address
                    string url = "http://" +
                        HttpContext.Current.Request.Url.Authority +
                        HttpContext.Current.Request.ApplicationPath;
                    if (!url.EndsWith("/"))
                        url = url + "/";

                    reqDetails.ReturnURL = url + "PaypalSuccess.aspx";
                    reqDetails.CancelURL = url + "Default.aspx";

                    reqDetails.NoShipping = "0";

                    reqDetails.LocaleCode = "US";
                    System.Globalization.CultureInfo cultureUS = System.Globalization.CultureInfo.GetCultureInfo("en-US");

                    reqDetails.PaymentAction = PaymentActionCodeType.Sale;
                    reqDetails.PaymentActionSpecified = true;
                    reqDetails.PaymentDetails = new PaymentDetailsType[1];
                    reqDetails.PaymentDetails[0] = new PaymentDetailsType();
                    reqDetails.PaymentDetails[0].PaymentDetailsItem = new PaymentDetailsItemType[prodList.Count + 2];

                    for (int i = 0; i < prodList.Count; i++)
                    {
                        reqDetails.PaymentDetails[0].PaymentDetailsItem[i] = new PaymentDetailsItemType();
                        reqDetails.PaymentDetails[0].PaymentDetailsItem[i].Amount = new BasicAmountType();
                        reqDetails.PaymentDetails[0].PaymentDetailsItem[i].Amount.currencyID = CurrencyCodeType.USD;
                        reqDetails.PaymentDetails[0].PaymentDetailsItem[i].Amount.Value = prodTable.Rows[i][2].ToString();
                        reqDetails.PaymentDetails[0].PaymentDetailsItem[i].Name = prodTable.Rows[i][0].ToString();
                        reqDetails.PaymentDetails[0].PaymentDetailsItem[i].Number = prodList[i].ProductId.ToString();
                        reqDetails.PaymentDetails[0].PaymentDetailsItem[i].Quantity = prodTable.Rows[i][1].ToString();
                        reqDetails.PaymentDetails[0].PaymentDetailsItem[i].Description = "Order #" + orderId.ToString();
                    }

                    this.Session.Add("orderId",orderId);

                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count] = new PaymentDetailsItemType();
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count].Amount = new BasicAmountType();
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count].Amount.currencyID = CurrencyCodeType.USD;
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count].Amount.Value = finalTable.Rows[0][1].ToString();
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count].Name = "Taxes";
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count].Number = "0";
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count].Quantity = "1";
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count].Description = "Total taxes (5% of each product)";

                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count + 1] = new PaymentDetailsItemType();
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count + 1].Amount = new BasicAmountType();
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count + 1].Amount.currencyID = CurrencyCodeType.USD;
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count + 1].Amount.Value = finalTable.Rows[1][1].ToString();
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count + 1].Name = "Shipping";
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count + 1].Number = "0";
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count + 1].Quantity = "1";
                    reqDetails.PaymentDetails[0].PaymentDetailsItem[prodList.Count + 1].Description = "Total shipping (5$ per item)";

                    reqDetails.PaymentDetails[0].OrderTotal = new BasicAmountType();
                    reqDetails.PaymentDetails[0].OrderTotal.currencyID = CurrencyCodeType.USD;
                    reqDetails.PaymentDetails[0].OrderTotal.Value = finalTable.Rows[2][1].ToString();

                    SetExpressCheckoutReq req = new SetExpressCheckoutReq()
                    {
                        SetExpressCheckoutRequest = new SetExpressCheckoutRequestType()
                        {
                            Version = PaypalUtility.Version,
                            SetExpressCheckoutRequestDetails = reqDetails
                        }
                    };

                    // query PayPal and get token
                    SetExpressCheckoutResponseType resp = PaypalUtility.BuildPayPalWebservice().SetExpressCheckout(req);
                    HandleError(resp);

                    /*Response.Cookies["order"].Value = orderId.ToString();
                    Response.Cookies["order"].Expires = DateTime.Now.AddDays(1);*/

                    // redirect user to PayPal
                    Response.Redirect(string.Format("{0}?cmd=_express-checkout&token={1}", ConfigurationManager.AppSettings["PayPalSubmitUrl"], resp.Token));
                }
            }
            else
            {
                lErrorMsg.Visible = true;
                lErrorMsg.Text = "Your password is incorrect.";
            }
        }

        internal static void HandleError(AbstractResponseType resp)
        {
            if (resp.Errors != null && resp.Errors.Length > 0)
            {
                // errors occured
                throw new Exception(
                    "Exception(s) occured when calling PayPal. First exception: " +
                    resp.Errors[0].LongMessage);
            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             }
    }
}